/**
 * Context 上下文对象
 *    作用: 解决组件层级嵌套过深，Props 逐级透传问题的。
 *
 *    使用：
 *      1. 通过 React.createContext() 创建一个 Context 上下文对象
 *        const MyContext = React.createContext(initalValue)
 *
 *      2. 可选 使用 创建出来的 Context 对象的 Provider 组件在提供数据的组件上使用
 *        <MyContext.Provider value="里斯">
            <div>
              <Hello />
            </div>
          </MyContext.Provider>

          value 属性的值，就是提供下去的数据
 *
 *      3. 后代组件中可以使用同一个 Context 对象的 Consumer 组件获取到数据
 *        <MyContext.Consumer>
            {(value) => (
              <div>
                <p>Hello</p>
                <p>value: {value}</p>
              </div>
            )}
          </MyContext.Consumer>
          
          1. Consumer 组件的 children 需要是 renderProp (函数返回ReactNode)
          2. renderProp 函数会收到一个 value 参数，
              如果外层组件有 Provider 包裹的化，该参数就是 Provider 组件传递下来的 value
              如果没有 Provider 包裹的话，该参数就是创建时设置的默认值


    函数组件中如何获取 Context 的数据
          1. 还是需要创建 Context 对象
          2. 可选的 Provider 提供数据下去
          3. 通过 useContext() hook 来使用即可。
 */

import React from "react";
import Hello from "./components/Hello";
import Msg from "./components/Msg";

// 引入 MyContext
import MyContext from "./contexts/MyContext";
import Counter from "./contexts/Counter";

interface Props {}
interface State {
  name: string;
  num: number;
}

class App extends React.Component<Props, State> {
  state = {
    name: "里斯",
    num: 1,
  };

  increment = () => {
    this.setState((prevState) => ({ num: prevState.num + 1 }));
  };

  render(): React.ReactNode {
    return (
      <MyContext.Provider value={this.state.name}>
        <Counter.Provider
          value={{ value: this.state.num, increment: this.increment }}
        >
          <div>
            <button onClick={() => this.setState({ name: "王五" })}>
              修改 name
            </button>
            <hr />
            <Hello />
            <hr />
            <Msg />
          </div>
        </Counter.Provider>
      </MyContext.Provider>
    );
  }
}
export default App;
